/**
 * 配置生产环境常用的配置: 让代码更稳、性能更好、更安全
 *
 *    1.当js/font/img提取到单独的文件夹中  js: 修改output.filename即可 |   font、img: 在对应的loader中配置一个options.outputPath属性
 *    2.将css提取到单独的文件夹中    npm i mini-css-extract-plugin -D
 *    3.压缩css代码                npm i optimize-css-assets-webpack-plugin -D
 *    4.css代码兼容性处理           npm i postcss-loader postcss-preset-env -D
 *    5.js代码兼容性处理            npm i babel-loader @babel/core @babel/preset-env core-js -D
 *    6.js代码和html代码压缩        生成模式
 */

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const { resolve } = require('path');

/**
 * 将 css提取到单独文件/处理css兼容性问题 抽取为一个公共变量, 供css/less/scss复用
 * Tips: 注意这个变量在 less/scss中摆放位置, 需要放在less-loader之后
 */
const commonCssLoader = [
  // 2.将css提取到单独文件
  {
    loader: MiniCssExtractPlugin.loader,
    options: {
      // 解决css中引入背景图片url路径问题
      // 这只改变打包后css文件中相对路径前缀, output中publicPath是改变全局的路径前缀
      // 比如, 根路径是 / , css文件所在的目录是 /css/ 因此相对路径是 ..
      publicPath: '../'
    }
  },
  'css-loader',
  // 4.css代码兼容性处理
  {
    loader: 'postcss-loader',
    options: {
      ident: 'postcss',
      plugins: () => [
        // postcss的插件
        require('postcss-preset-env')()
      ]
    }
  }
]


module.exports = {
  entry: './src/index.js',
  output: {
    // 1.将js文件配置到单独的文件夹中
    filename: 'js/built.js',
    path: resolve(__dirname, 'build'),
  },
  // 6.生产模式下可以实现对js代码进行压缩
  mode: 'production',
  module: {
    rules: [
      // 4.解决js代码兼容性问题
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: {
          // 预设: 指示babel做怎么样的兼容性处理
          presets: [
            [
              // (1)这个只能做一些简单的语法兼容性, 箭头函数
              '@babel/preset-env',
              // (2)使用corejs, 可以实现高级的语法兼容性, 这两个加起来, 解决了js语法兼容性问题
              {
                useBuiltIns: 'usage',
                corejs: {
                  version: 3
                },
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '60',
                  edge: '60',
                }
              }
            ]
          ]
        }
      },
      // 配置css
      {
        test: /\.(css)$/,
        use: [...commonCssLoader],
      },
      // 配置less
      {
        test: /\.(less)$/,
        use: [...commonCssLoader, 'less-loader'],
      },
      // 配置图片
      {
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',
        options: {
          limit: 10 * 1000,
          name: '[hash:8].[ext]',
          // Tips: webpack v4.44.6版本问题, 使用esModule关闭es6模块化
          esModule: false,
          // 1.配置outputPath可以将图片资源单独打包到 build/img/ 目录中
          outputPath: 'img'
        }
      },
      {
        test: /\.(html)$/,
        loader: 'html-loader',
        options: {
          name: '[hash:8].[ext]',
        }
      },
      // 配置其他资源, 如字体
      {
        exclude: /\.(css|less|js|json|html|jpg|png|gif)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:8].[ext]',
          // 1.
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      // 6.压缩html代码
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    }),
    // 2.将css提取到单独文件
    new MiniCssExtractPlugin({
      filename: 'css/app.css'
    }),
    // 3.压缩css代码
    new OptimizeCssAssetsWebpackPlugin()
  ],
  resolve: {
    // 自动补全的扩展名
    extensions: ['.js', '.vue', '.json'],
    // 默认路径代码
    alias: {
      // 这样
      '@': resolve('src'),
      'src': resolve(__dirname, '../src')
    }
  },
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    port: 3000,
    compress: true
  }
}
